const fs = require('fs')
const path = require('path')
const MFS = require('memory-fs')
const mfs = new MFS()
const webpack = require('webpack')
const chokidar = require('chokidar')
const clientConfig = require('./webpack.client.config')
const serverConfig = require('./webpack.server.config')
const { devMiddleware, hotMiddleware } = require('koa-webpack-middleware')

const readFile = (fs, file) => {
  try {
    return fs.readFileSync(path.join(clientConfig.output.path, file), 'utf-8')
  } catch (e) {}
}

module.exports = function setupDevServer (app, templatePath, cb) {
  let bundle
  let template
  let clientManifest

  let ready
  const readyPromise = new Promise(r => { ready = r })
  const update = () => {
    if (bundle && clientManifest) {
      ready()
      cb(bundle, {
        template,
        clientManifest
      })
    }
  }
	
	//从磁盘和表读取模板
	  template = fs.readFileSync(templatePath, 'utf-8')
    chokidar.watch(templatePath).on('change', () => {
	    template = fs.readFileSync(templatePath, 'utf-8')
	    console.log('index.html template updated.')
	    update()
  })
	
	//修改客户端配置 使用热更新
	clientConfig.entry.main = ['webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000', clientConfig.entry.main]
  clientConfig.output.filename = '[name].js'
  clientConfig.plugins.push(
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoEmitOnErrorsPlugin()
  )
	
	//开发 中间件 
	const clientCompiler = webpack(clientConfig)
  const koaDevMiddleware = devMiddleware(clientCompiler, {
    publicPath: clientConfig.output.publicPath,
    noInfo: true
  })
	
  app.use(koaDevMiddleware)
  clientCompiler.plugin('done', stats => {
    stats = stats.toJson()
    stats.errors.forEach(err => console.error(err))
    stats.warnings.forEach(err => console.warn(err))
    if (stats.errors.length) return
    clientManifest = JSON.parse(readFile(
      koaDevMiddleware.fileSystem,
      'vue-ssr-client-manifest.json'
    ))
    update()
  })
	
	//热更新 中间件
	app.use(hotMiddleware(clientCompiler, { heartbeat: 5000 }))
	
	//查看 更新服务器 渲染器
	const serverCompiler = webpack(serverConfig)
	
	serverCompiler.outputFileSystem = mfs
  serverCompiler.watch({}, (err, stats) => {
  	
    if (err) throw err
    stats = stats.toJson()
    if (stats.errors.length) return
		
		//文件包生成
		//打印读取的文件系统 Json文件
		bundle = JSON.parse(readFile(mfs, 'vue-ssr-server-bundle.json'))
    update()
	})
	
	return readyPromise
}
